package com.huayu.languo.common.configurer;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

import javax.annotation.PostConstruct;

@EnableCaching
@Configuration
@EnableRedisHttpSession(redisNamespace = "${project.root.package}")
@Slf4j
public class RedisConfig {

    @PostConstruct
    public void init() {
        log.warn("线程:" + Thread.currentThread().getName());
    }

    @Async
    public void async() {
        log.warn("线程:" + Thread.currentThread().getName());
    }


    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory, RedisSerializer fastRedisSerializer) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        //key采用String的序列化方式 ,使用StringRedisSerializer来序列化和反序列化redis的key值
        StringRedisSerializer strSerializer = new StringRedisSerializer();
        template.setKeySerializer(strSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(strSerializer);
        // value序列化方式采用 fastjson
        template.setValueSerializer(fastRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(fastRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory, RedisSerializer fastRedisSerializer) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        //key采用String的序列化方式 ,使用StringRedisSerializer来序列化和反序列化redis的key值
        StringRedisSerializer strSerializer = new StringRedisSerializer();
        template.setKeySerializer(strSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(strSerializer);
        // value序列化方式采用 fastjson
        template.setValueSerializer(fastRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(fastRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public RedisSerializer fastRedisSerializer() {
        FastJson2JsonRedisSerializer<Object> fastSerializer = new FastJson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        fastSerializer.setObjectMapper(mapper);
        return fastSerializer;
    }


    // @Bean //????????????????? TODO
    // public static ConfigureRedisAction configureRedisAction() {
    // // 让springSession不再执行config命令
    // return ConfigureRedisAction.NO_OP;
    // }

}
